<template>
    <uploadFile :isEndUpload="isEndUpload" :uploadType="'message'">
        <SvgIcon name="file" width="1.8rem" height="1.8rem"></SvgIcon>
    </uploadFile>
    <el-dialog
        v-model="dialogVisible"
        width="400"
        align-center
        :close-on-click-modal="false"
        @close="cancle"
    >
        <template #header>
            <span class="send">发送给：</span>
        </template>
        <div class="userInfo">
            <img :src="messageStore.chattingFriend.avatar" class="avatar" />
            <span class="realname">
                {{ messageStore.chattingFriend.realname }}
            </span>
        </div>
        <div class="fileInfo">
            <div class="fileLeft">
                <img :src="userFile.previewUrl" alt="预览图加载失败" class="file" />
                <span class="filename">{{ userFile.fileName }}</span>
            </div>
            <span class="filesize">{{ userFile.fileSize }}</span>
        </div>
        <template #footer>
            <div class="dialog-footer">
                <el-button @click="cancle">取消</el-button>
                <el-button type="primary" @click="sendFile">发送</el-button>
            </div>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { reactive, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import type { UploadRawFile } from 'element-plus'
import type { messageFormData } from '@/api/messages/type'
import type { FileData } from '@/api/file/type'
import useUserStore from '@/store/modules/user'
import useMessageStore from '@/store/modules/messages'
import useWebSocketStore from '@/store/modules/wschat'
import { save } from '@/utils/savemessage'
import { saveFile, readBlobAsBase64 } from '@/utils/chatfile'

// 用户仓库
const userStore = useUserStore()
// 聊天信息仓库
const messageStore = useMessageStore()
// webSocket仓库
const webSocketStore = useWebSocketStore()
// 用户选择的文件
let userFile = reactive<FileData>({
    fileType: '',
    fileData: null,
    fileName: '',
    fileSize: '',
    previewUrl: '',
    fileWidth: 0,
    fileHeight: 0,
})
// 用户是否结束上传操作
const isEndUpload = ref<boolean>(false)
// 控制文件上传提示是否可见
const dialogVisible = ref<boolean>(false)

// 聊天消息对象
const reqmessage = reactive<messageFormData>({
    message_type: '',
    conversation_id: messageStore.chattingFriend.conversation_id,
    sender_id: userStore.userId,
    receiver_id: messageStore.chattingFriend.userId,
    message_content: '',
    send_time: 0,
})

//取消上传文件的方法
const cancle = () => {
    dialogVisible.value = false
    isEndUpload.value = true
    messageStore.selectedFile = null
}

//定义消息内容
const setContent = (message_type: string) => {
    switch (message_type) {
        case 'audioFile':
            return '[音频]'
        case 'video':
            return '[视频]'
        case 'picture':
            return '[图片]'
        case 'emoji':
            return '[动画表情]'
        case 'file':
            return '[文档]'
        default:
            return '[文档]'
    }
}

//发送文件的方法
const sendFile = async () => {
    //获取文件
    const rawFile = userFile.fileData
    //消息类型
    reqmessage.message_type = userFile.fileType
    //定义消息内容
    reqmessage.message_content = setContent(reqmessage.message_type)
    //文件发送时间
    reqmessage.send_time = Date.now()
    //文件大小
    reqmessage.media_size = userFile.fileSize
    //文件在服务端的保存路径
    reqmessage.media_url = `/chatAppServer/${reqmessage.message_type}/${userFile.fileName}`
    //图片和视频加入宽和高
    if (reqmessage.message_type === 'picture' || reqmessage.message_type === 'video') {
        reqmessage.preview_url = userFile.previewUrl
        reqmessage.file_width = userFile.fileWidth
        reqmessage.file_height = userFile.fileHeight
    }
    //等待media赋值成功
    try {
        reqmessage.media = await readBlobAsBase64(rawFile as Blob)
    } catch (error) {
        ElMessage.error('读取文件失败')
        return false
    }

    if (webSocketStore.isConnected) {
        try {
            //将文件保存到本地
            await saveFile(reqmessage.message_type, rawFile as UploadRawFile, userFile.fileName)
            await messageStore.sendMessage(reqmessage)
            webSocketStore.sendMessage(reqmessage)
        } catch (error) {
            ElMessage.error('消息发送失败，请稍后重试')
            return false
        }
        //发送成功将消息存到本地和仓库中
        messageStore.conversations = save(messageStore.conversations, reqmessage)
        messageStore.selectedFile = null
    } else {
        ElMessage({
            type: 'error',
            message: '网络未连接，请检查网络状态',
        })
        return false
    }

    dialogVisible.value = false
    isEndUpload.value = true
    messageStore.selectedFile = null
    return true
}

// 监听用户是否选择了文件
watch(
    () => messageStore.selectedFile,
    (newVal) => {
        if (newVal) {
            dialogVisible.value = true
            isEndUpload.value = false
            userFile = newVal
        }
    },
)
</script>

<style scoped lang="scss">
.send {
    font-size: 1.2rem;
}

.userInfo {
    border-bottom: 2px solid rgb(214, 214, 214);
    @include flex-layout(flex, center);

    .avatar {
        width: 4rem;
        height: 4rem;
        border-radius: 0.5rem;
        margin: 0.5rem 0;
    }

    .realname {
        height: 1.5rem;
        line-height: 1.5rem;
        font-size: 1.5rem;
        margin-left: 1rem;
        color: black;
    }
}

.fileInfo {
    width: 100%;
    @include flex-layout(flex, center, space-between, nowrap, row);

    .fileLeft {
        @include flex-layout(flex, center);

        .file {
            width: 4rem;
            height: 4rem;
            border-radius: 0.5rem;
            margin: 0.5rem 0;
            object-fit: cover;
        }

        .filename {
            @include ellipsis-multiple(-webkit-box, 2, 10rem);
            max-height: calc($base-menu-height - 1.1rem);
            line-height: 1.3rem;
            font-size: 1rem;
            margin-left: 1rem;
            color: black;
            align-items: start;
        }
    }

    .filesize {
        height: calc($base-menu-height - 1rem);
        line-height: 1.3rem;
        font-size: 1rem;
        @include flex-layout(flex, center);
    }
}
</style>
